package Game;

import java.io.*;
import java.net.*;

public class Server extends ServerSocket {
    private Doorman accepter;
    private int user_count = 0;

    //Serversettings
    private String IP = InetAddress.getLocalHost().toString().split("/")[1];
    private int port;
    private int myIndex;

    //Arrays
    private Client[] clients = new Client[0];
    private String[] IPs = new String[0];
    private int max;

    //Flags
    private boolean isMain;
    private boolean isReady = false;
    private boolean isRunning = true;

    // <editor-fold defaultstate="collapsed" desc="Nonsense">
    private final static String[] NUMERALS = {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth"};
    // </editor-fold>

    public Server(int port, int max) throws IOException {
        super(port);
        this.port = port;
        this.isMain = true;
        this.max = (max != -1) ? max : Integer.MAX_VALUE;
        accepter = new Doorman(this);
        accepter.start();
    }

    public Server(int port, int max, int myIndex) throws IOException {
        super(port);
        this.port = port;
        this.isMain = false;
        this.myIndex = myIndex;
        this.max = (max != -1) ? max : Integer.MAX_VALUE;
        accepter = new Doorman(this);
        accepter.start();
    }

    public int getUserCount(){
        return user_count;
    }

    public void startPeerToPeer(){
        accepter.finish();
        for (int i = 0; i < clients.length; i++){
            clients[i].sendResponse();
            clients[i].sendInt(user_count);
            //wait for client to start Server
            clients[i].requestResponse();
            for (int j = 0; j <= i; j++){
                clients[i].sendLine(IPs[j]);
            }
        }
        for (int i = 0; i < clients.length; i++){
            clients[i].sendResponse();
        }
        closeServer();
    }

    public Client[] getClients(){
        return clients;
    }

    public boolean isReady() {
        return isReady;
    }

    private void closeServer() {
        for (int i = 0; i < clients.length; i++){
            try {
                clients[i].close();
            }
            catch (IOException ex){
                ex.printStackTrace();
            }
        }
        Thread.currentThread().interrupt();
        //System.exit(0);
    }

    class Doorman extends Thread {

        private Server server;
        
        public Doorman(Server server) {
            this.server = server;
        }

        @Override
        public void run() {
            while (check()){
                try {
                    System.out.print("Waiting for " + NUMERALS[user_count] + " Connection...");
                    Socket socket = server.accept();
                    if (!isRunning){
                        System.out.println("Abort");
                        break;
                    }
                    if (isMain){
                        addToClientList(new Client(socket, user_count));
                        clients[user_count].sendInt(user_count);
                        addToIPList(clients[user_count].receiveLineWait());
                    }
                    else {
                        addToClientList(new Client(socket, (user_count+myIndex)));
                    }
                    user_count++;
                    System.out.println("done");
                }
                catch (Exception ex){
                    ex.printStackTrace();
                }
            }
            System.out.println("Doorman: All Connections liaised");
            isReady = true;
            if (isMain){
                server.startPeerToPeer();
            }
        }

        private boolean check(){
            if (isRunning && max > user_count){
                return true;
            }
            else {
                return false;
            }
        }

        private void addToClientList(Client client){
            Client[] temp = clients;
            clients = new Client[temp.length+1];
            for (int i = 0; i < temp.length; i++){
                clients[i] = temp[i];
            }
            clients[temp.length] = client;
        }

        private void addToIPList(String IP){
            String[] temp = IPs;
            IPs = new String[temp.length+1];
            for (int i = 0; i < temp.length; i++){
                IPs[i] = temp[i];
            }
            IPs[temp.length] = IP;
        }

        public void finish() {
            isRunning = false;
            try {
                new Socket(IP, port);
            }
            catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }

}
